﻿
// 2018/8/10: 首个规范化版本
// 2018/11/29: 增加Protocols静态属性
// 2019/3/22: 时间戳赋值
// 2019/3/29: 添加注释
// 2019/12/25: 添加若干标签种类
// 2020/1/14: 接口完备性

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using ASEva;

namespace ImageLabelSampleV1
{
    enum ImageLabelClass
    {
        Unknown = 0, // 未知

        Auto = 100, // 机动车大类
        Car = 101, // 轿车
        Bus = 102, //大巴
        Midibus = 103, // 小巴
        Truck = 104, // 货车
        Van = 105, // 面包车
        Semitrailer = 106, // 货柜车
        Trailer = 107, // 拖车
        SUV = 108, // SUV
        TinyCar = 109, // 微型车

        Minor = 200, // 弱势参与者大类
        Ped = 201, // 行人
        Bicycle = 202, // 自行车
        Tricycle = 203, // 三轮车
        Motorbike = 204, // 摩托车
        Wheelchair = 205, // 轮椅
        Animal = 206, // 动物

        Static = 300, // 静态目标大类
        ZebraCrossing = 301, // 斑马线
        TrafficLight = 302, // 交通灯
        TrafficSign = 303, // 交通信号
        ParkingSlot = 304, // 车位
        Cone = 305, // 锥形路障
        ManholeCover = 306, // 井盖
        Patch = 307, // 路面补丁
        Gantry = 308, // 龙门架
        Pole = 309, // 竖杆
        Tree = 310, // 树木
        Vegetation = 311, // 灌木
        Building = 312, // 建筑物
    }

    class ImageLabel
    {
        public ImageLabelClass Class { get; set; } //标签类型
        public int ID { get; set; } //标签ID
        public double Distance { get; set; } //标签距离 m
        public RectangleF Rect { get; set; } //标签矩形框
    }

    class ImageLabelSample : Sample
    {
        public Size ImageSize { get; set; } //标签尺寸
        public List<ImageLabel> Labels { get; set; } //标签列表

        public ImageLabelSample()
        {
            Labels = new List<ImageLabel>();
        }

        public static string Title
        {
            get
            {
                return "Related video channel,Video frame width,Video frame height,Label count,First label's class,First label's ID,First label's distance,First label's top,First label's bottom,First label's left,First label's right,Second label's class,etc";
            }
        }

        public static string Protocol
        {
            get
            {
                return "image-label-sample-v1";
            }
        }

        public static string[] Protocols
        {
            get
            {
                return new string[] { "image-label-sample-v1" };
            }
        }

        public override string GetGeneralSampleProtocol()
        {
            return Protocol;
        }

        public override string[] GetGeneralSampleProtocols()
        {
            return Protocols;
        }

        public override bool FromGeneralSample(GeneralSample sample)
        {
            if (sample.Protocol == "image-label-sample-v1")
            {
                var v = sample.Values.ToArray();
                if (v.Length < 4) return false;
                if (v[0].IsNotNumber() || v[0].number != sample.Channel.Value) return false;

                if (v[1].IsNotNumber() ||
                    v[2].IsNotNumber() ||
                    v[3].IsNotNumber()) return false;

                int width = (int)v[1].number;
                int height = (int)v[2].number;
                int nLabels = (int)v[3].number;
                if (v.Length != 4 + nLabels * 7) return false;

                ImageSize = new Size(width, height);

                Labels.Clear();
                for (int i = 0; i < nLabels; i++)
                {
                    var label = new ImageLabel();
                    label.Class = (ImageLabelClass)(int)v[7 * i + 4].number;
                    label.ID = (int)v[7 * i + 5].number;
                    label.Distance = v[7 * i + 6].number;

                    var left = (float)v[7 * i + 7].number;
                    var top = (float)v[7 * i + 8].number;
                    var right = (float)v[7 * i + 9].number;
                    var bottom = (float)v[7 * i + 10].number;
                    label.Rect = new RectangleF(left, top, right - left, bottom - top);

                    Labels.Add(label);
                }

                Base = sample.Base;
                Offset = sample.Offset;
                Timeline = sample.Timeline;

                return true;
            }

            return false;
        }
    }
}
